package com.wstuo.common.security.dao;

import com.wstuo.common.dao.BaseDAOImplHibernate;
import com.wstuo.common.dto.PageDTO;
import com.wstuo.common.security.dto.OrganizationDTO;
import com.wstuo.common.security.dto.OrganizationQueryDTO;
import com.wstuo.common.security.entity.Organization;
import com.wstuo.common.util.StringUtils;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import java.util.List;

/**
 * 机构DAO.
 * 
 * @author will
 */
@SuppressWarnings("unchecked")
public class OrganizationDAO extends BaseDAOImplHibernate<Organization> implements IOrganizationDAO {

	/**
	 * 分页查找机构列表.
	 * 
	 * @param qdto
	 *            查询DTO OrganizationQueryDTO
	 * @return 分页数据 PageDTO
	 */
	public PageDTO findPager(OrganizationQueryDTO qdto) {
		final DetachedCriteria dc = DetachedCriteria.forClass(Organization.class);
		dc.add(Restrictions.in("orgType", new String[]{"inner", "services"}));
		int start = 0;
		int limit = 10;
		if (qdto != null) {
			start = qdto.getStart();
			limit = qdto.getLimit();
			
			if (qdto.getOrgNos() != null && qdto.getOrgNos().length > 0) {
				dc.add(Restrictions.in("orgNo", qdto.getOrgNos()));
			}
			if (StringUtils.hasText(qdto.getOrgName())) {
				dc.add(Restrictions.like("orgName", qdto.getOrgName(), MatchMode.ANYWHERE));
			}
			if (StringUtils.hasText(qdto.getOfficePhone())) {

				dc.add(Restrictions.like("officePhone", qdto.getOfficePhone(), MatchMode.ANYWHERE));
			}

			if (StringUtils.hasText(qdto.getAddress())) {
				dc.add(Restrictions.like("address", qdto.getAddress(), MatchMode.ANYWHERE));
			}
			if (StringUtils.hasText(qdto.getEmail())) {
				dc.add(Restrictions.like("email", qdto.getEmail(), MatchMode.ANYWHERE));
			}
			if (StringUtils.hasText(qdto.getPersonInChargeName())) {
				dc.createAlias("personInCharge", "pi").add(Restrictions.eq("pi.fullName", qdto.getPersonInChargeName()));
			}
			if (null != qdto.getCompanyNo()) {
				dc.add(Restrictions.like("path", qdto.getCompanyNo()+"/", MatchMode.START));
			}
			if(null != qdto.getParentNo()){
				dc.add(Restrictions.eq("parentNo", qdto.getParentNo()));
			}
			
			// 排序
			if (StringUtils.hasText(qdto.getSord()) && StringUtils.hasText(qdto.getSidx())) {
				if ("desc".equals(qdto.getSord())) {
					dc.addOrder(Order.desc(qdto.getSidx()));
				} else {
					dc.addOrder(Order.asc(qdto.getSidx()));
				}
			} else {
				dc.addOrder(Order.desc("orgNo"));
			}
		}
		return super.findPageByCriteria(dc, start, limit, null);
	}

	/**
	 * 根据传入的编号数据查询机构分页
	 * 
	 * @param qdto
	 *            查询DTO OrganizationQueryDTO
	 * @return 分页数据 PageDTO
	 */
	public PageDTO findPagerByIds(OrganizationQueryDTO qdto) {
		PageDTO dto = null;
		final DetachedCriteria dc = DetachedCriteria.forClass(Organization.class);
		int start = 0;
		int limit = 0;

		if ((qdto != null) && (qdto.getOrgNos() != null)) {
			start = qdto.getStart();
			limit = qdto.getLimit();

			dc.add(Restrictions.in("orgNo", qdto.getOrgNos()));

			dto = super.findPageByCriteria(dc, start, limit);
		}

		return dto;
	}

	/**
	 * 根据父机构查找子机构列表.
	 * 
	 * @param parentNo
	 *            父机构编号Long
	 * @return 子机构列表List<Organization>
	 */
	public List<Organization> findByParent(Long parentNo) {
		String hql = " from Organization og where og.parentOrg.orgNo=" + parentNo;

		return super.getHibernateTemplate().find(hql);
	}

	// 最迟的编号
	public static Long latesOrganizationNo = 0L;

	/**
	 * 直接设置.
	 * 
	 * @param no
	 */
	public void setLatesOrganizationNo(Long no) {

		synchronized (this) {
			latesOrganizationNo = no;
		}
	}

	/**
	 * 累加机构编号.
	 */
	public void increment() {
		synchronized (this) {
			latesOrganizationNo += 1;
		}
	}

	/**
	 * 取得最新的编号.
	 * 
	 * @return long
	 */
	public Long getLatestOrganizationNo() {
		synchronized (this) {
			return latesOrganizationNo;
		}
	}

	/**
	 * 取得下一个编号.
	 * 
	 * @return next org no
	 */
	public Long getNextOrgNo() {
		Long v = 1L;
		final String hql = "select max(o.orgNo) from Organization o";
		List list = getHibernateTemplate().find(hql);

		if (list != null && list.size() > 0) {
			Number n = (Number) list.get(0);
			if (n != null) {
				v = n.longValue() + 1;
			}
		}
		return v;
	}

	/**
	 * 重写SAVE方法.
	 * 
	 * @param entity
	 */
	@Override
	public void save(Organization entity) {

		if (entity.getOrgNo() == null || entity.getOrgNo() == 0) {
			entity.setOrgNo(getLatestOrganizationNo());
		} else {

			if (entity.getOrgNo() > getLatestOrganizationNo()) {

				setLatesOrganizationNo(entity.getOrgNo());
			}

		}

		super.save(entity);
		increment();// 自增1.

	}

	/**
	 * 重写merge方法
	 * 
	 * @param entity
	 * @return Organization
	 */
	@Override
	public Organization merge(Organization entity) {

		if (entity.getOrgNo() != null) {
			if (entity.getOrgNo() >= getLatestOrganizationNo()) {
				setLatesOrganizationNo(entity.getOrgNo() + 1);
			}
		} else {
			increment();// 自增1.
		}

		return super.merge(entity);
	}

	/**
	 * 查询最上层公司(机构)
	 * @return Organization
	 */
	public Organization findTopCompany() {
		Organization organization = null;
		final DetachedCriteria dc = DetachedCriteria.forClass(Organization.class);
		dc.add(Restrictions.eq("orgType", "company"));
		List<Organization> orgs = getHibernateTemplate().findByCriteria(dc);
		if (orgs != null && orgs.size() > 0) {
			organization = orgs.get(0);
		}

		return organization;
	}

	/**
	 * 查询指定的OrgId
	 * 
	 * @param ids
	 * @return List<Organization>
	 */
	public List<Organization> findOrganizationsByIds(Long[] ids) {
		final DetachedCriteria dc = DetachedCriteria.forClass(Organization.class);
		dc.add(Restrictions.in("orgNo", ids));

		return super.getHibernateTemplate().findByCriteria(dc);
	}

	/**
	 * 查询子机构
	 * 
	 * @param parentOrgNo
	 * @return List<Organization>
	 */
	public List<Organization> findSubOrg(Long parentOrgNo) {
		final DetachedCriteria dc = DetachedCriteria.forClass(Organization.class);
		dc.createAlias("parentOrg", "parentOrg");
		dc.add(Restrictions.eq("parentOrg.orgNo", parentOrgNo));
		return super.getHibernateTemplate().findByCriteria(dc);
	}

	/**
	 * 根据机构名称查询
	 * 
	 * @param orgName
	 * @return List<Organization>
	 */
	public List<Organization> findOrgByName(String orgName) {
		final DetachedCriteria dc = DetachedCriteria.forClass(Organization.class);
		dc.add(Restrictions.eq("orgName", orgName));
		return super.getHibernateTemplate().findByCriteria(dc);
	}
	/**
	 * 根据机构名称查询
	 * 
	 * @param orgName
	 * @return List<Organization>
	 */
	public List<Organization> findOrgByOrgNameOrparentOrgName(String orgName,String parentOrgName) {
		final DetachedCriteria dc = DetachedCriteria.forClass(Organization.class);
		if(StringUtils.hasText(orgName)){
			dc.add(Restrictions.eq("orgName", orgName));
		}
		dc.createAlias("parentOrg", "parentOrg");
		if(StringUtils.hasText(parentOrgName)){
			dc.add(Restrictions.eq("parentOrg.orgName", parentOrgName));
		}
		
		return super.getHibernateTemplate().findByCriteria(dc);
	}
	/**
	 * 根据Path查询机构下所有子机构ID
	 * @return List<Long>
	 */
	public List findOrgChildsIdsByPath(String orgPath){
		final DetachedCriteria dc = DetachedCriteria.forClass(Organization.class);
		dc.setProjection(Projections.projectionList()
				.add(Projections.property("orgNo")));
		dc.add(Restrictions.like("path", orgPath,MatchMode.ANYWHERE));
		return getHibernateTemplate().findByCriteria(dc);
	}
	
	/**
     * 判断分类是否存在
     * @param ec
     */
    public boolean isCategoryExisted(OrganizationDTO dto) {
        final DetachedCriteria dc = DetachedCriteria.forClass(Organization.class);
        
        dc.add(Restrictions.eq("orgName", dto.getOrgName()));
        dc.add(Restrictions.eq("parentOrg.orgNo", dto.getParentOrgNo()));
        dc.add(Restrictions.eq("orgType", dto.getOrgType()));
        
        List<Organization> organizations = getHibernateTemplate().findByCriteria(dc);
        
        return !organizations.isEmpty();
        
    }

}
